package com.mls.fivedistrict.server.impl;

import com.alibaba.druid.util.StringUtils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.github.pagehelper.util.StringUtil;
import com.mls.fivedistrict.common.PageFilter;
import com.mls.fivedistrict.common.ServiceResponse;
import com.mls.fivedistrict.dao.UserAuthMapper;
import com.mls.fivedistrict.dao.UserMapper;
import com.mls.fivedistrict.enums.*;
import com.mls.fivedistrict.exception.CustomerException;
import com.mls.fivedistrict.pojo.*;
import com.mls.fivedistrict.server.*;
import com.mls.fivedistrict.util.JsonUtils;
import com.mls.fivedistrict.util.TimeUtils;
import com.mls.fivedistrict.util.jedis.RedisPoolUtil;
import com.sun.org.apache.bcel.internal.generic.NEW;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

import static java.math.BigDecimal.ROUND_DOWN;

/**
 * Created by chenxiuxiang on 2018/4/1.
 */
@Service("userAuthService")
public class UserAuthServiceImpl implements UserAuthService {

    @Resource(name = "userMapper")
    UserMapper userMapper;
    @Resource(name = "userAuthMapper")
    UserAuthMapper userAuthMapper;
    @Resource(name = "userService")
    UserService userService;
    @Resource(name = "taskService")
    TaskService taskService;
    @Resource(name = "userTaskService")
    UserTaskService userTaskService;
    @Resource(name = "calculateService")
    CalculateService calculateService;
    @Resource(name = "integralService")
    IntegralService integralService;

    @Resource(name = "recordService")
    RecordService recordService;
    @Resource(name = "userAuthRecordService")
    UserAuthRecordService userAuthRecordService;
    @Autowired
    private SendMessageUtil sendMessageUtil;

    @Autowired
    private TaskRewardService taskRewardService;

    @Autowired
    private UserRoleService userRoleService;

    @Autowired
    private PropertyService propertyService;

    @Autowired
    private UserAuthRewardRecordService userAuthRewardRecordService;
    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Transactional
    @Override
    public int addAuth(UserAuth userAuth, String token) {

        User userDetail = userService.getUserDetail(userAuth.getUserId());
        if (!StringUtils.isEmpty(userDetail.getRealname())) {
            throw new CustomerException("已完成实名认证请勿重复操作");
        }
        Task faceTask = taskService.getTaskByCategory("face_recognition");
        Optional.ofNullable(faceTask).orElseThrow(() -> new CustomerException("人脸识别任务不存在"));
        UserTask userTask = userTaskService.getUserTask(faceTask.getId(), userAuth.getUserId());
        Optional.ofNullable(userTask).orElseThrow(() -> new CustomerException("请先完成人脸识别任务"));
        String cradNo = userAuth.getCradNo();
        UserAuthExample userAuthExample = new UserAuthExample();
        UserAuthExample.Criteria criteria = userAuthExample.createCriteria();
        criteria.andCradNoEqualTo(cradNo);
        List<String> status = new ArrayList<>();
        status.add(AuthStatusEnum.REJECT.getValue());
        status.add(AuthStatusEnum.LOGOUT.getValue());
        criteria.andStatusNotIn(status);
        List<UserAuth> userAuths = userAuthMapper.selectByExample(userAuthExample);
        if (userAuths.size() > 0) {
            throw new CustomerException("身份信息已存在");
        }
        //查询用户有没有申请记录
        UserAuthExample rejectExample = new UserAuthExample();
        UserAuthExample.Criteria rejectCriteria = rejectExample.createCriteria();
        rejectCriteria.andUserIdEqualTo(userAuth.getUserId());
//        rejectCriteria.andStatusEqualTo(AuthStatusEnum.REJECT.getValue());
        List<UserAuth> userRejectAuths = userAuthMapper.selectByExample(rejectExample);
        if (userRejectAuths.size() > 0) {
            userAuth.setId(userRejectAuths.get(0).getId());
            userAuth.setAuthCount(userRejectAuths.get(0).getAuthCount() + 1);
        } else {
            userAuth.setAuthCount(1);
        }
        User user = new User();
        user.setId(userAuth.getUserId());
        user.setRealname(userAuth.getRealName());
        userService.editUser(user);
        //用户完成实名认证给邀请人增加算力 代表邀请人完成了这次【任务】
//        User userDetail = userService.getUserDetail(userAuth.getUserId());
        CalculateAndProperty invationCalculateAndProperty;
        if (userDetail.getInviterUserId() != null) {
            User inviterUser = userService.getUserDetail(userDetail.getInviterUserId());
            if (inviterUser != null) {
                //获取邀请任务的任务ID
                Task invitationTask = taskService.getTaskByCategory(TaskCategoryEnum.INVITE_FRIENDS.getValue());
                if (invitationTask == null) {
                    throw new CustomerException("邀请任务不存在");
                }
                invationCalculateAndProperty = taskService.completeTaskForInviterAuth(invitationTask.getId(), inviterUser.getId());
                userAuth.setInvitationCalculateId(invationCalculateAndProperty.getCalculateId());
                userAuth.setInvitationPropertyId(invationCalculateAndProperty.getPropertyId());
                userAuth.setInvitationCalculateValue(invitationTask.getValue().intValue());
                userAuth.setInvitationIntrgralValue(invitationTask.getIntrgralValue());
            }
        }
        Task authenTask = taskService.getTaskByCategory("authentication");
        //标记用户完成实名认证任务
        if (authenTask == null) {
            //代表不存在这条任务
            throw new CustomerException("任务不存在");
        }
        CalculateAndProperty authCalculateAndProperty = taskService.completeTaskForAuth(authenTask.getId(), userAuth.getUserId());
        userAuth.setCalculateId(authCalculateAndProperty.getCalculateId());
        userAuth.setIntrgralValue(authenTask.getIntrgralValue());
        userAuth.setStatus("");
        int insert = 0;
        if (userAuth.getId() != null) {
            insert = userAuthMapper.updateByPrimaryKeySelective(userAuth);
        } else {
            insert = userAuthMapper.insertSelective(userAuth);
        }
        return insert;
    }


    @Override
    public UserAuth getUserAuth(String idNo) {
        UserAuthExample userAuthExample = new UserAuthExample();
        UserAuthExample.Criteria criteria = userAuthExample.createCriteria();
        criteria.andCradNoEqualTo(idNo);
        List<UserAuth> userAuths = userAuthMapper.selectByExample(userAuthExample);
        if (userAuths.size() > 0) {
            return userAuths.get(0);
        }
        return null;
    }

    @Override
    public PageInfo getUserAuthList(PageFilter pageFilter) {
        UserAuthExample userAuthExample = new UserAuthExample();
        UserAuthExample.Criteria criteria = userAuthExample.createCriteria();
        Optional.ofNullable(pageFilter.getFilterMap().get("cradNo")).map(cradNo -> criteria.andCradNoEqualTo(cradNo));
        Optional.ofNullable(pageFilter.getFilterMap().get("realName")).map(realName -> criteria.andRealNameLike("%" + realName + "%"));
        Optional.ofNullable(pageFilter.getFilterMap().get("startDate")).map(startDate -> criteria.andCreateDateGreaterThan(TimeUtils.millis2Date(Long.parseLong(startDate))));
        Optional.ofNullable(pageFilter.getFilterMap().get("endDate")).map(endDate -> criteria.andCreateDateLessThanOrEqualTo(TimeUtils.millis2Date(Long.parseLong(endDate))));
        String phone = pageFilter.getFilterMap().get("phone");
        if (!StringUtil.isEmpty(phone)) {
            User user = userService.getUserByPhone(phone);
            if (user != null) {
                criteria.andUserIdEqualTo(user.getId());
            }
        }
        PageHelper.startPage(pageFilter.getPageNum(), pageFilter.getPageSize());
        List<UserAuth> userAuths = userAuthMapper.selectByExample(userAuthExample);
        PageInfo pageInfo = new PageInfo(userAuths);
        return pageInfo;
    }

    @Transactional
    @Override
    public int editUserAuth(UserAuth userAuth, String token) {
        String nowStatus = "";
        if (userAuth.getCreateBy().equals("system_auto")) {
            return userAuthMapper.updateByPrimaryKeySelective(userAuth);
        }
        if (userAuth.getStatus() != null && (userAuth.getStatus().equals(AuthStatusEnum.REJECT.getValue()) ||
                userAuth.getStatus().equals(AuthStatusEnum.LOGOUT.getValue()))) {
            //用户本身状态 防止状态相同更新
            String sourceStatus = userAuth.getStatus();
            userAuth = userAuthMapper.selectByPrimaryKey(userAuth.getId());
            //现在数据库认证的状态 不为空 表名已经审核过
            nowStatus = userAuth.getStatus();
            if (userAuth.getStatus() != null && userAuth.getStatus().equals(sourceStatus)) {
                return -1;
            }
            userAuth.setStatus(sourceStatus);
            //将用户表中用户的userName清空 减去实名认证赠送的算力
            //4-8日修改为：一旦驳回删除用户所有的积分和算力
            User userDetail = userService.getUserDetail(userAuth.getUserId());
            if (userDetail == null) {
                return 0;
            }
            UserAuth newUserAuth = userAuthMapper.selectByPrimaryKey(userAuth.getId());
            if (userDetail != null) {
                User user = new User();
                user.setId(userDetail.getId());
                user.setRealname("");
                user.setCalculate(0);
                if (userAuth.getStatus().equals(AuthStatusEnum.LOGOUT.getValue())) {
                    //代表注销用户
                    user.setIsDelete(true);
                    RedisPoolUtil.del(userDetail.getPhone());
                }
                userService.editUser(user);
                //2.删除算力表中记录
                calculateService.deleteUserCalculate(userDetail.getId());
                //3.删除用户资产
                propertyService.deleteUserProperty(userDetail.getId(), sourceStatus);
            }
            //删除用户实名认证的任务
            Task taskByCategory = taskService.getTaskByCategory(TaskCategoryEnum.AUTHENTICATION.getValue());
            userTaskService.deleteTask(taskByCategory.getId(), userDetail.getId());
            //如果有邀请人 减去邀请人的算力和资产
            //1.减去邀请人用户表中的算力
            if (!StringUtils.isEmpty(userAuth.getCreateBy()) && userAuth.getCreateBy().equals("system")) {
                //代表新接口
                recycleReward(userAuth);
            } else {
                User invitationUser = userService.getUserDetail(userDetail.getInviterUserId());
                if (invitationUser != null) {

                    //代表有邀请人
                    User newUser = new User();
                    newUser.setCalculate(invitationUser.getCalculate() - newUserAuth.getInvitationCalculateValue());
                    newUser.setId(invitationUser.getId());
                    userService.editUser(newUser);
                    //2.删除算力表中的记录
                    if (newUserAuth.getInvitationCalculateId() != null)
                        calculateService.deleteCalculate(newUserAuth.getInvitationCalculateId());
                    //3.减去资产
                    BigDecimal invitationIntrgralValue = userAuth.getInvitationIntrgralValue();
                    Long invitationPropertyId = userAuth.getInvitationPropertyId();
                    if (invitationPropertyId != null) {
                        Property invitationProperty = propertyService.getPropertyDetail(invitationPropertyId);
                        if (invitationProperty != null) {
                            Property newInvitationProperty = new Property();
                            newInvitationProperty.setId(invitationProperty.getId());
                            BigDecimal total = invitationProperty.getTotal();
                            int zero = total.compareTo(BigDecimal.ZERO);
                            if (zero > 0) {
                                newInvitationProperty.setTotal(invitationProperty.getTotal().subtract(invitationIntrgralValue).setScale(8, ROUND_DOWN));
                                propertyService.editProperty(newInvitationProperty);
                                //回收到积分池
                                Integral integralDetail = integralService.getIntegralDetail(invitationProperty.getIntegralId());
                                Integral integral = new Integral();
                                integral.setId(invitationProperty.getIntegralId());
                                integral.setResidueIntegral(integralDetail.getResidueIntegral().add(invitationIntrgralValue).setScale(8, ROUND_DOWN));
                                integralService.editIntegral(integral);
                                String subPhone = userDetail.getPhone().substring(userDetail.getPhone().length() - 4, userDetail.getPhone().length());
                                //写入新的记录值为减少
                                Record record = new Record();
                                record.setPropertyId(invitationProperty.getId());
                                record.setValue(invitationIntrgralValue.negate());
                                if (userAuth.getStatus().equals(AuthStatusEnum.REJECT.getValue())) {
                                    record.setSource("好友实名认证虚假被驳回*" + subPhone);
                                    record.setChangeReason("好友实名认证虚假被驳回*" + subPhone);
                                } else if (userAuth.getStatus().equals(AuthStatusEnum.LOGOUT.getValue())) {
                                    record.setSource("好友实名认证虚假被注销*" + subPhone);
                                    record.setChangeReason("好友实名认证虚假被注销*" + subPhone);
                                }
                                record.setUserId(invitationUser.getId());
                                record.setStatus(RecordStatusEnum.ALREADYRECEIVE.getValue());
                                record.setIntergralId(invitationProperty.getIntegralId());
                                recordService.addRecord(record);
                            }
                        }
                    }

                }
            }

//            if (userAuth.getStatus().equals(AuthStatusEnum.REJECT.getValue())) {
//                sendMessageUtil.sendMessageByType(userDetail.getPhone(), CaptchaTypeEnum.REJECTAUTH.getType());
//            } else if (userAuth.getStatus().equals(AuthStatusEnum.LOGOUT.getValue())) {
//                sendMessageUtil.sendMessageByType(userDetail.getPhone(), CaptchaTypeEnum.LOGOUTTEMPLATECODE.getType());
//            }
            //添加审批记录
            UserAuthRecord userAuthRecord = JsonUtils.jsonToPojo(JsonUtils.objectToJson(userAuth), UserAuthRecord.class);
            userAuthRecord.setAuthId(userAuth.getId());
            userAuthRecord.setId(new UserAuthRecord().getId());
//            UserManager userManager = JsonUtils.jsonToPojo(RedisPoolUtil.get(token), UserManager.class);
            userAuthRecord.setUpdateBy("system");
            userAuthRecord.setSourceStatus(nowStatus);
            userAuthRecord.setEditType(UserAuthEnumType.EDITSTATUS.getValue());
            userAuthRecordService.addAuthRecord(userAuthRecord);
            userAuth.setUpdateDate(new Date());
            return userAuthMapper.updateByPrimaryKeySelective(userAuth);
        }


        return userAuthMapper.updateByPrimaryKeySelective(userAuth);

    }

    /**
     * 回收奖励
     *
     * @param userAuth
     * @param
     */
    private void recycleReward(UserAuth userAuth) {
        User userDetail = userService.getUserDetail(userAuth.getUserId());
        String subPhone = userDetail.getPhone().substring(userDetail.getPhone().length() - 4, userDetail.getPhone().length());
        List<UserAuthRewardRecord> userAuthRewardRecords = userAuthRewardRecordService.getUserAuthRewardRecordByUserAuthId(userAuth.getId());
        if (userAuthRewardRecords != null && userAuthRewardRecords.size() > 0) {
            UserAuthRewardRecord userAuthRewardRecord = userAuthRewardRecords.get(0);
            Long oneLevelUserId = userAuthRewardRecord.getOneLevelUserId();
            Long secondLevelUserId = userAuthRewardRecord.getSecondLevelUserId();
            recyclingOneReward(userAuthRewardRecord, oneLevelUserId, "好友实名认证虚假被驳回*" + subPhone);
            recyclingSecondReward(userAuthRewardRecord, secondLevelUserId, "二级好友实名认证虚假被驳回*" + subPhone);
            //删除认证奖励记录
            UserAuthRewardRecord newUserAuthRewardRecord = new UserAuthRewardRecord();
            newUserAuthRewardRecord.setId(userAuthRewardRecord.getId());
            newUserAuthRewardRecord.setDelete(true);
            userAuthRewardRecordService.updateById(newUserAuthRewardRecord);
        }
    }

    /**
     * 回收一二级奖励
     */
    private void recyclingOneReward(UserAuthRewardRecord userAuthRewardRecord, Long oneLevelUserId, String reason) {
        if (oneLevelUserId != 0) {
            //代表有一级邀请用户
            //1.减去一级邀请人的算力
            if (userAuthRewardRecord.getOneLevelCalculateId() != 0) {
                User oneUserDetail = userService.getUserDetail(oneLevelUserId);
                User newOneUser = new User();
                newOneUser.setId(oneLevelUserId);
                Calculate calculate = calculateService.getCalculateById(userAuthRewardRecord.getOneLevelCalculateId());
                newOneUser.setCalculate(oneUserDetail.getCalculate() - calculate.getValue());
                userService.editUser(newOneUser);
                //删除算力记录
                Calculate newCalculate = new Calculate();
                newCalculate.setId(calculate.getId());
                newCalculate.setIsDelete(true);
                calculateService.editCalculate(newCalculate);

            }
            //1.1减去一级邀请人的积分
            if (userAuthRewardRecord.getOneLevelIntegralId() != 0) {
                //1.1.1 插入减去记录
                Record record = new Record();
                record.setStatus(RecordStatusEnum.ALREADYRECEIVE.getValue());
                record.setIntergralId(userAuthRewardRecord.getOneLevelIntegralId());
                record.setChangeReason(reason);
                record.setSource(RecordChangeReason.SPITE.getValue());
                record.setUserId(oneLevelUserId);
                record.setValue(userAuthRewardRecord.getOneLevelIntegralValue().negate());
                recordService.insertRecord(record);
                //1.1.2 减去资产
                Property propertyDetail = propertyService.getPropertyDetailByIntegral(userAuthRewardRecord.getOneLevelIntegralId(), oneLevelUserId);
                propertyService.reducePropertyTotal(oneLevelUserId, userAuthRewardRecord.getOneLevelIntegralId(), userAuthRewardRecord.getOneLevelIntegralValue());
                //回收到积分池
                Integral integralDetail = integralService.getIntegralDetail(userAuthRewardRecord.getOneLevelIntegralId());
                Integral integral = new Integral();
                integral.setId(userAuthRewardRecord.getOneLevelIntegralId());
                integral.setResidueIntegral(integralDetail.getResidueIntegral().add(userAuthRewardRecord.getOneLevelIntegralValue()).setScale(8, ROUND_DOWN));
                integralService.editIntegral(integral);
            }

        }
    }

    private void recyclingSecondReward(UserAuthRewardRecord userAuthRewardRecord, Long secondLevelUserId, String reason) {
        if (secondLevelUserId != 0) {
            //代表有二级邀请用户
            //1. 减去二级邀请人的算力
            if (userAuthRewardRecord.getTwoLevelCalculateId() != 0) {
                User twoUserDetail = userService.getUserDetail(secondLevelUserId);
                User newTwoUser = new User();
                newTwoUser.setId(secondLevelUserId);
                Calculate calculate = calculateService.getCalculateById(userAuthRewardRecord.getTwoLevelCalculateId());
                newTwoUser.setCalculate(twoUserDetail.getCalculate() - calculate.getValue());
                userService.editUser(newTwoUser);
                //减去算力记录
                Calculate newCalculate = new Calculate();
                newCalculate.setId(calculate.getId());
                newCalculate.setIsDelete(true);
                calculateService.editCalculate(newCalculate);
            }
            //2.减去二级邀请人的积分
            if (userAuthRewardRecord.getTwoLevelIntegralId() != 0) {
                //2.1插入减去记录
                Record record = new Record();
                record.setStatus(RecordStatusEnum.ALREADYRECEIVE.getValue());
                record.setIntergralId(userAuthRewardRecord.getTwoLevelIntegralId());
                record.setChangeReason(reason);
                record.setSource(RecordChangeReason.SPITE.getValue());
                record.setUserId(secondLevelUserId);
                record.setValue(userAuthRewardRecord.getTwoLevelIntegralValue().negate());
                recordService.insertRecord(record);
                //1.1.2 减去资产
                Property propertyDetail = propertyService.getPropertyDetailByIntegral(userAuthRewardRecord.getTwoLevelIntegralId(), secondLevelUserId);
                propertyService.reducePropertyTotal(secondLevelUserId, userAuthRewardRecord.getTwoLevelIntegralId(), userAuthRewardRecord.getTwoLevelIntegralValue());
                //回收到积分池
                Integral integralDetail = integralService.getIntegralDetail(userAuthRewardRecord.getTwoLevelIntegralId());
                Integral integral = new Integral();
                integral.setId(userAuthRewardRecord.getTwoLevelIntegralId());
                integral.setResidueIntegral(integralDetail.getResidueIntegral().add(userAuthRewardRecord.getTwoLevelIntegralValue()).setScale(8, ROUND_DOWN));
                integralService.editIntegral(integral);
            }
        }
    }

    @Override
    public UserAuth getUserAuth(Long id) {
        return userAuthMapper.selectByPrimaryKey(id);
    }

    @Override
    public ServiceResponse search(PageFilter pageFilter) {
        Map<String, String> maps = pageFilter.getFilterMap();
        Map<String, Object> params = new HashMap<>();
        maps.forEach((k, v) -> {
            if (!StringUtil.isEmpty(v)) {
                if (k.equals("startDate") || k.equals("endDate")) {
                    params.put(k, TimeUtils.millis2Date(Long.parseLong(v)));
                } else {
                    params.put(k, v);
                }
            }
        });
        Object phone = params.get("phone");
        if (phone != null) {
            User user = userService.getUserByPhone(phone.toString().trim());
            params.put("user_id", user.getId() + "");
            params.remove("phone");
        }
        PageHelper.startPage(pageFilter.getPageNum(), pageFilter.getPageSize());
        List<UserAuthAndUser> userAuthAndUsers = userAuthMapper.selectAndUser(params);
        PageInfo pageInfo = new PageInfo(userAuthAndUsers);
        return ServiceResponse.createSuccessResponse(pageInfo);
    }

    @Override
    public User getUserByPhone(String phone) {
        UserExample userExample = new UserExample();
        UserExample.Criteria criteria = userExample.createCriteria();
        criteria.andPhoneEqualTo(phone);
        List<User> userList = userMapper.selectByExample(userExample);
        if (userList != null && userList.size() >= 1) {
            return userList.get(0);
        }
        return null;
    }

    @Transactional
    @Override
    public ServiceResponse editUserAuthAndUser(UserAuthAndUser userAuthAndUser, String token) {
        UserAuth userAuth = userAuthMapper.selectByPrimaryKey(userAuthAndUser.getId());
        String sourceName = userAuth.getRealName();
        String sourceNo = userAuth.getCradNo();
        if (!userAuth.getCradNo().equals(userAuthAndUser.getCradNo())) {
            int count = userAuthMapper.getUserByCraNoCount(userAuthAndUser.getCradNo());
            if (count > 0) {
                return ServiceResponse.createErrorResponse("已有此身份证");
            }
        }
        User user = userService.getUserDetail(userAuth.getUserId());
        userAuth.setCradNo(userAuthAndUser.getCradNo());
        userAuth.setRealName(userAuthAndUser.getRealName());
        user.setRealname(userAuthAndUser.getRealName());
        user.setPhone(userAuthAndUser.getPhone());
        int row = userAuthMapper.updateByPrimaryKeySelective(userAuth);
        if (row <= 0) {
            return ServiceResponse.createErrorResponse("更新用户认证失败");
        }
        row = userService.editUser(user);
        if (row <= 0) {
            return ServiceResponse.createErrorResponse("更新用户认证失败");
        }
        //添加审批记录
        UserAuthRecord userAuthRecord = JsonUtils.jsonToPojo(JsonUtils.objectToJson(userAuth), UserAuthRecord.class);
        userAuthRecord.setAuthId(userAuth.getId());
        userAuthRecord.setId(new UserAuthRecord().getId());
        ManagerUser userManager = JsonUtils.jsonToPojo(RedisPoolUtil.get(token), ManagerUser.class);
        userAuthRecord.setUpdateBy(userManager.getUsername());
        userAuthRecord.setSourceName(sourceName);
        userAuthRecord.setSourceNo(sourceNo);
        userAuthRecord.setEditType(UserAuthEnumType.EDITINFO.getValue());
        userAuthRecordService.addAuthRecord(userAuthRecord);
        return ServiceResponse.createSuccessResponse("更新成功");
    }

    @Override
    public ServiceResponse getUserUnactivateTotal() {
        UserAuthExample userAuthExample = new UserAuthExample();
        UserAuthExample.Criteria criteria = userAuthExample.createCriteria();
        criteria.andStatusNotEqualTo("pass");
        long personSum = userAuthMapper.countByExample(userAuthExample);
        return ServiceResponse.createSuccessResponse(personSum);
    }

    @Override
    public ServiceResponse getUserActivateTotal() {
        UserAuthExample userAuthExample = new UserAuthExample();
        UserAuthExample.Criteria criteria = userAuthExample.createCriteria();
        criteria.andStatusEqualTo("pass");
        long personSum = userAuthMapper.countByExample(userAuthExample);
        return ServiceResponse.createSuccessResponse(personSum);
    }

    @Override
    public int userAuth(UserAuth userAuth) {
        userAuth.setCreateBy("system");
        User userDetail = userService.getUserDetail(userAuth.getUserId());
        if (userDetail.getIsDelete()) {
            return -2;
        }
        if (!StringUtils.isEmpty(userDetail.getRealname())) {
            throw new CustomerException("已完成实名认证请勿重复操作");
        }
        Task faceTask = taskService.getTaskByCategory("face_recognition");
        Optional.ofNullable(faceTask).orElseThrow(() -> new CustomerException("人脸识别任务不存在"));
        UserTask userTask = userTaskService.getUserTask(faceTask.getId(), userAuth.getUserId());
        Optional.ofNullable(userTask).orElseThrow(() -> new CustomerException("请先完成人脸识别任务"));
        String cradNo = userAuth.getCradNo();
        UserAuthExample userAuthExample = new UserAuthExample();
        UserAuthExample.Criteria criteria = userAuthExample.createCriteria();
        criteria.andCradNoEqualTo(cradNo);
        List<String> status = new ArrayList<>();
        status.add(AuthStatusEnum.REJECT.getValue());
        status.add(AuthStatusEnum.LOGOUT.getValue());
        criteria.andStatusNotIn(status);
        List<UserAuth> userAuths = userAuthMapper.selectByExample(userAuthExample);
        if (userAuths.size() > 0) {
            String status1 = userAuths.get(0).getStatus();
            if (status1.equals("")) {
                throw new CustomerException("审核中");
            }
            throw new CustomerException("身份信息已存在");
        }
        //查询用户有没有申请记录
        UserAuthExample rejectExample = new UserAuthExample();
        UserAuthExample.Criteria rejectCriteria = rejectExample.createCriteria();
        rejectCriteria.andUserIdEqualTo(userAuth.getUserId());
        List<UserAuth> userRejectAuths = userAuthMapper.selectByExample(rejectExample);
        if (userRejectAuths.size() > 0) {
            userAuth.setId(userRejectAuths.get(0).getId());
            userAuth.setAuthCount(userRejectAuths.get(0).getAuthCount() + 1);
        } else {
            userAuth.setAuthCount(1);
        }
        User user = new User();
        user.setId(userAuth.getUserId());
        user.setRealname(userAuth.getRealName());
        userService.editUser(user);
        userAuth.setStatus("");
        int insert = 0;
        if (userAuth.getId() != null) {
            insert = userAuthMapper.updateByPrimaryKeySelective(userAuth);
        } else {
            insert = userAuthMapper.insertSelective(userAuth);
        }
        if (insert <= 0) {
            throw new CustomerException("认证失败");
        }
//        //用户完成实名认证给邀请人增加算力 代表邀请人完成了这次【任务】
        UserAuthRewardRecord userAuthRewardRecord = new UserAuthRewardRecord();
        Task authTask = taskService.getTaskByCategory(TaskCategoryEnum.AUTHENTICATION.getValue());
        userAuthRewardRecord = completeOneSelfTask(authTask, userDetail.getId(), CalculateSourceEnum.Authentication.getValue(), RecordProductTypeEnum.AUTHENTICATION.getValue(), CalculateSourceEnum.Authentication.getDesc(), userAuthRewardRecord);
        if (userDetail.getInviterUserId() != null && userDetail.getInviterUserId() != 0) {
            userAuthRewardRecord = distributionRewards(authTask.getId(), userDetail.getId(), CalculateSourceEnum.Invite.getValue(), RecordProductTypeEnum.INVITE_FRIENDS.getValue(), CalculateSourceEnum.Invite.getDesc(), CalculateSourceEnum.SecondInvite.getValue(), RecordProductTypeEnum.SECOND_INVITE.getValue(), CalculateSourceEnum.SecondInvite.getDesc(), userAuthRewardRecord);
            userAuthRewardRecord.setUserId(userAuth.getUserId());
            userAuthRewardRecord.setUserAuthId(userAuth.getId());
            boolean flag = userAuthRewardRecordService.insert(userAuthRewardRecord);
            if (!flag) {
                throw new CustomerException("认证奖励记录创建失败");
            }

        }

        return insert;
    }

    @Override
    public int updateUserAuth(UserAuth userAuth) {
        int i = userAuthMapper.updateByPrimaryKeySelective(userAuth);
        return i;
    }

    @Override
    public Long autoUserAuth(UserAuth userAuth) {
        userAuth.setCreateBy("system_auto");
        User userDetail = userService.getUserDetail(userAuth.getUserId());
        if (!StringUtils.isEmpty(userDetail.getRealname())) {
            throw new CustomerException("已完成实名认证请勿重复操作");
        }
        Task faceTask = taskService.getTaskByCategory("face_recognition");
        Optional.ofNullable(faceTask).orElseThrow(() -> new CustomerException("人脸识别任务不存在"));
        UserTask userTask = userTaskService.getUserTask(faceTask.getId(), userAuth.getUserId());
        Optional.ofNullable(userTask).orElseThrow(() -> new CustomerException("请先完成人脸识别任务"));
        String cradNo = userAuth.getCradNo();
        UserAuthExample userAuthExample = new UserAuthExample();
        UserAuthExample.Criteria criteria = userAuthExample.createCriteria();
        criteria.andCradNoEqualTo(cradNo);
        List<String> status = new ArrayList<>();
        status.add(AuthStatusEnum.REJECT.getValue());
        status.add(AuthStatusEnum.LOGOUT.getValue());
        criteria.andStatusNotIn(status);
        List<UserAuth> userAuths = userAuthMapper.selectByExample(userAuthExample);
        if (userAuths.size() > 0) {
            UserAuth userAuth1 = userAuths.get(0);
            String status1 = userAuths.get(0).getStatus();
            if (userAuth.getUserId().equals(userAuth1.getUserId()) && status1.equals("")) {
                throw new CustomerException("审核中");
            }
            throw new CustomerException("身份信息已存在");
        }
        //查询用户有没有申请记录
        UserAuthExample rejectExample = new UserAuthExample();
        UserAuthExample.Criteria rejectCriteria = rejectExample.createCriteria();
        rejectCriteria.andUserIdEqualTo(userAuth.getUserId());
        List<UserAuth> userRejectAuths = userAuthMapper.selectByExample(rejectExample);
        if (userRejectAuths.size() > 0) {
            userAuth.setId(userRejectAuths.get(0).getId());
            userAuth.setAuthCount(userRejectAuths.get(0).getAuthCount() + 1);
        } else {
            userAuth.setAuthCount(1);
        }
        userAuth.setStatus("");
        userAuth.setReason("");
        int insert = 0;
        if (userAuth.getId() != null) {
            insert = userAuthMapper.updateByPrimaryKeySelective(userAuth);
        } else {
            insert = userAuthMapper.insertSelective(userAuth);
        }
        if (insert <= 0) {
            throw new CustomerException("认证失败");
        }
        //将实名认证任务发送到队列
        rabbitTemplate.convertAndSend("extractExchange", "authenticationQueue", JsonUtils.objectToJson(userAuth));

        return userAuth.getId();
    }

    /**
     * 实名认证完成发放奖励
     */
    public UserAuthRewardRecord distributionRewards(Long taskId, Long userId, String oneCalculateSource, String oneRecordSource, String oneReason, String twoCalculateSource, String twoRecordSource, String twoReason, UserAuthRewardRecord userAuthRewardRecord) {
        TaskReward taskReward = taskRewardService.getTaskRewardByTaskID(taskId);
        if (taskReward == null) {
            return null;
        }
        Long oneLevelRoleId = taskReward.getOneLevelRoleId();
        if (oneLevelRoleId != 0) {
            //1.判断一级角色为-1代表所有一级用户都可以获得 为0代表上级没有奖励
            User userDetail = userService.getUserDetail(userId);
            User inviteUser = userService.getUserDetail(userDetail.getInviterUserId());
//            User inviteUser = userDetail.getInviterUser();
            if (oneLevelRoleId == -1) {
                userAuthRewardRecord.setOneLevelUserId(inviteUser.getId());
                rewardOneLevel(taskReward, inviteUser, oneCalculateSource, oneRecordSource, oneReason, userAuthRewardRecord);
            } else {
                //2.判断上级邀请人是否含有此角色
                List<UserRole> inviteUserRoleList = userRoleService.getUserRoleByUserId(inviteUser.getId());
                boolean hasRole = false;
                for (UserRole userRole : inviteUserRoleList) {
                    if (userRole.getRoleId().equals(oneLevelRoleId)) {
                        hasRole = true;
                    }
                }
                if (hasRole) {
                    userAuthRewardRecord.setOneLevelUserId(inviteUser.getId());
                    rewardOneLevel(taskReward, inviteUser, oneCalculateSource, oneRecordSource, oneReason, userAuthRewardRecord);
                }
            }

        }
        Long twoLevelRoleId = taskReward.getTwoLevelRoleId();
        if (twoLevelRoleId != 0) {
            //1.判断二级角色为-1代表所有一级用户都可以获得 为0代表没有奖励
            User userDetail = userService.getUserDetail(userId);
            User inviteUser = userService.getUserDetail(userDetail.getInviterUserId());
//            User inviteUser = userDetail.getInviterUser();
            User secondUser = userService.getUserDetail(inviteUser.getInviterUserId());
            if (twoLevelRoleId == -1 && secondUser != null) {
                userAuthRewardRecord.setSecondLevelUserId(secondUser.getId());
                rewardSecondLevel(taskReward, secondUser, twoCalculateSource, twoRecordSource, twoReason, userAuthRewardRecord);

            } else if (secondUser != null) {
                userAuthRewardRecord.setSecondLevelUserId(secondUser.getId());
                //2.判断上级邀请人是否含有此角色
                List<UserRole> inviteUserRoleList = userRoleService.getUserRoleByUserId(secondUser.getId());
                boolean hasRole = false;
                for (UserRole userRole : inviteUserRoleList) {
                    if (userRole.getRoleId().equals(twoLevelRoleId)) {
                        hasRole = true;
                    }
                }
                if (hasRole) {
                    rewardSecondLevel(taskReward, secondUser, twoCalculateSource, twoRecordSource, twoReason, userAuthRewardRecord);
                }
            }
        }
        return userAuthRewardRecord;
    }

    /**
     * 完成任务
     *
     * @param task
     * @param userId
     * @param calculateSource
     * @param recordSource
     */
    private UserAuthRewardRecord completeOneSelfTask(Task task, Long userId, String calculateSource, String recordSource, String reason, UserAuthRewardRecord userAuthRewardRecord) {
        //1.判断用户是否已经完成过
        UserTask userTask = userTaskService.getUserTask(task.getId(), userId);
        if (userTask != null) {
            throw new CustomerException("任务已经完成，请勿重复提交");
        }
        int calculateValue = task.getValue().intValue();
        if (calculateValue > 0) {
            Calculate calculate = new Calculate();
            calculate.setUserId(userId);
            calculate.setValue(calculateValue);
            calculate.setType(task.getCalculateType());
            calculate.setSource(calculateSource);
            calculate.setChangeDescription(reason);
            Long calculateId = calculateService.insertCalculate(calculate);
            userAuthRewardRecord.setCalculateId(calculateId);
        }
        Long integralId = task.getIntegralId();
        if (integralId != null) {
            BigDecimal integralValue = task.getIntrgralValue();
            //添加积分
            Long propertyId = propertyService.addPropertyByIntegral(integralId, integralValue, userId);
            //添加记录
            Record record = new Record();
            record.setChangeReason(reason);
            record.setSource(recordSource);
            record.setUserId(userId);
            record.setIntergralId(integralId);
            record.setValue(integralValue);
            record.setStatus(RecordStatusEnum.ALREADYRECEIVE.getValue());
            record.setPropertyId(propertyId);
            recordService.insertRecordForId(record);
            userAuthRewardRecord.setIntegralId(integralId);
            userAuthRewardRecord.setIntegralValue(integralValue);
        }
        //
        UserTask addUserTask = new UserTask();
        addUserTask.setUserId(userId);
        addUserTask.setTaskId(task.getId());
        userTaskService.addUserTask(addUserTask);
        return userAuthRewardRecord;

    }


    /**
     * 发放一级奖励
     *
     * @param taskReward
     * @param inviteUser
     * @param userAuthRewardRecord
     */
    public void rewardOneLevel(TaskReward taskReward, User inviteUser, String calculateSource, String recordSource, String reason, UserAuthRewardRecord userAuthRewardRecord) {
        //为一级用户发放奖励
        long oneLevelIntegralId = taskReward.getOneLevelIntegralId();
        if (oneLevelIntegralId != 0) {

            //为一级用户添加积分
            BigDecimal oneLevelIntegralValue = taskReward.getOneLevelIntegralValue();
            Long propertyId = propertyService.addPropertyByIntegral(oneLevelIntegralId, oneLevelIntegralValue, inviteUser.getId());
            //添加记录
            Record record = new Record();
            record.setChangeReason(reason);
            record.setSource(recordSource);
            record.setUserId(inviteUser.getId());
            record.setIntergralId(oneLevelIntegralId);
            record.setValue(oneLevelIntegralValue);
            record.setStatus(RecordStatusEnum.ALREADYRECEIVE.getValue());
            record.setPropertyId(propertyId);
            recordService.insertRecordForId(record);
            userAuthRewardRecord.setOneLevelIntegralId(oneLevelIntegralId);
            userAuthRewardRecord.setOneLevelIntegralValue(oneLevelIntegralValue);
        }
        int oneLevelCalculateValue = taskReward.getOneLevelCalculateValue();
        if (oneLevelCalculateValue > 0) {
            //为一级用户添加算力
            Calculate calculate = new Calculate();
            calculate.setUserId(inviteUser.getId());
            calculate.setValue(oneLevelCalculateValue);
            calculate.setType(taskReward.getOneLevelCalculateType());
            calculate.setSource(calculateSource);
            calculate.setChangeDescription(reason);
            Long calculateId = calculateService.insertCalculate(calculate);
            userAuthRewardRecord.setOneLevelCalculateId(calculateId);

        }
    }

    /**
     * 发放二级奖励
     *
     * @param taskReward
     * @param secondUser
     */
    public void rewardSecondLevel(TaskReward taskReward, User secondUser, String calculateSource, String recordSource, String reason, UserAuthRewardRecord userAuthRewardRecord) {
        //为二级用户发放奖励
        long twoLevelIntegralId = taskReward.getTwoLevelIntegralId();
        if (twoLevelIntegralId != 0) {
            //为二级用户添加积分
            BigDecimal twoLevelIntegralValue = taskReward.getTwoLevelIntegralValue();
            Long propertyId = propertyService.addPropertyByIntegral(twoLevelIntegralId, twoLevelIntegralValue, secondUser.getId());
            //添加记录
            Record record = new Record();
            record.setChangeReason(reason);
            record.setSource(recordSource);
            record.setUserId(secondUser.getId());
            record.setIntergralId(twoLevelIntegralId);
            record.setValue(twoLevelIntegralValue);
            record.setStatus(RecordStatusEnum.ALREADYRECEIVE.getValue());
            record.setPropertyId(propertyId);
            recordService.insertRecordForId(record);
            userAuthRewardRecord.setTwoLevelIntegralId(twoLevelIntegralId);
            userAuthRewardRecord.setTwoLevelIntegralValue(twoLevelIntegralValue);
        }
        int twoLevelCalculateValue = taskReward.getTwoLevelCalculateValue();
        if (twoLevelCalculateValue > 0) {
            //为二级用户添加算力
            Calculate calculate = new Calculate();
            calculate.setUserId(secondUser.getId());
            calculate.setValue(twoLevelCalculateValue);
            calculate.setType(taskReward.getOneLevelCalculateType());
            calculate.setSource(calculateSource);
            calculate.setChangeDescription(reason);
            Long calculateId = calculateService.insertCalculate(calculate);
            userAuthRewardRecord.setTwoLevelCalculateId(calculateId);
        }
    }


}
